import threading
import time
import logging
from app.extensions import db
from app.models import Video
from app.utils.redis_utils import redis_utils

# 配置日志
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)

class ScheduledTasks:
    """
    定时任务管理类
    负责管理所有定期执行的任务，如Redis数据同步到数据库
    """
    
    def __init__(self):
        """
        初始化定时任务管理器
        """
        self._stop_event = threading.Event()
        self._tasks = []
    
    def start_view_count_sync_task(self):
        """
        启动观看次数同步任务
        定期将Redis中的观看次数同步到数据库
        """
        def sync_view_counts():
            while not self._stop_event.is_set():
                try:
                    logger.info("开始同步Redis观看次数到数据库...")
                    # 执行同步操作
                    self._sync_view_counts_to_db()
                    logger.info("同步Redis观看次数完成")
                except Exception as e:
                    logger.error(f"同步Redis观看次数失败: {str(e)}")
                
                # 等待下一次执行，每5分钟同步一次
                time.sleep(300)  # 5分钟 = 300秒
        
        # 创建并启动线程
        task_thread = threading.Thread(target=sync_view_counts, daemon=True)
        task_thread.start()
        self._tasks.append(task_thread)
        logger.info("观看次数同步任务已启动")
    
    def _sync_view_counts_to_db(self):
        """
        将Redis中的观看次数同步到数据库
        """
        # 获取所有视频ID列表
        video_ids = redis_utils.get_all_video_ids_for_sync()
        
        if not video_ids:
            logger.info("没有需要同步的观看次数")
            return
        
        logger.info(f"找到 {len(video_ids)} 个视频需要同步观看次数")
        
        # 批量获取视频信息
        videos = Video.query.filter(Video.id.in_(video_ids)).all()
        
        # 创建视频ID到视频对象的映射
        video_map = {video.id: video for video in videos}
        
        # 批量更新观看次数
        updated_count = 0
        for video_id in video_ids:
            # 从Redis获取最新的观看次数
            redis_view_count = redis_utils.get_view_count(video_id)
            
            # 如果视频存在于数据库中
            if video_id in video_map:
                video = video_map[video_id]
                # 只有当Redis中的观看次数大于数据库中的观看次数时才更新
                if redis_view_count > video.view_count:
                    video.view_count = redis_view_count
                    updated_count += 1
        
        # 提交更改到数据库
        if updated_count > 0:
            db.session.commit()
            logger.info(f"成功更新 {updated_count} 个视频的观看次数")
    
    def start_all_tasks(self):
        """
        启动所有定时任务
        """
        self.start_view_count_sync_task()
    
    def stop_all_tasks(self):
        """
        停止所有定时任务
        """
        self._stop_event.set()
        
        # 等待所有任务线程结束
        for task in self._tasks:
            if task.is_alive():
                task.join(timeout=5)  # 等待最多5秒
        
        logger.info("所有定时任务已停止")

# 创建全局定时任务管理器实例
scheduled_tasks = ScheduledTasks()